The WebworkWebflow project integrates Spring Webflow with Webwork

Project Team

  • Tom Schneider

Requirements

  • Spring 2.0+
  • Spring Webflow 1.0+
  • Webwork 2.2.4+
  • WebworkWebflow 1.0.0+

Prerequisite

For background information on the core Spring Webflow concepts, visit http://www.ervacon.com/products/swf/intro/.

Step 1 - Create your flow definition xml

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow
                          http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

	<start-state idref="ageEnter" />

	<view-state id="ageEnter" view="ageEnter">
		<transition on="submit" to="AgeSave" />
	</view-state>

	<view-state id="ageEnterJSP" view="ageEnter">
		<transition on="input" to="enterAgeJSP" />
		<transition on="submit" to="AgeSave" />
	</view-state>

	<action-state id="AgeSave">
		<action bean="webworkFlowAdapter"/>
		<transition on="input" to="enterAgeJSP" />
		<transition on="success" to="calcRate" />
	</action-state>

	<view-state id="calcRate" view="calcRate">
		<transition on="finish" to="finish" />
	</view-state>

	<end-state id="finish" view="finish"/>
</flow>

Step 2 - Configure Spring's applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:flow="http://www.springframework.org/schema/webflow-config"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/webflow-config
           http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">

	<!-- Launches new flow executions and resumes existing executions. -->
	<flow:executor id="flowExecutor" registry-ref="flowRegistry">
		<flow:execution-attributes>
		  <flow:alwaysRedirectOnPause value="false"/>
		</flow:execution-attributes>
	</flow:executor>

	<!-- Creates the registry of flow definitions for this application -->
	<flow:registry id="flowRegistry">
		<flow:location path="/WEB-INF/flows/**-flow.xml"/>
	</flow:registry>

	<bean id="webworkFlowAdapter" class="com.googlecode.webworkwebflow.WebworkFlowAdapter"></bean>
</beans>

The WebworkFlowAdapter allows a webwork action to execute a webflow action-state. The WebworkFlowAdapter uses the id of the action state as the name of webwork action to execute. The alwaysRedirectOnPause is disabled because whether to redirect or not is easier to control in the webwork configuration files.

Step 3 - Add SWF interceptors to webwork's xwork.xml configuration file

<interceptors>
  <interceptor name="sessionFlowExecKey" class="com.googlecode.webworkwebflow.SessionFlowExecKeyInterceptor"/>
  <interceptor name="flowScope" class="com.googlecode.webworkwebflow.FlowScopeInterceptor">
    <param name="flowScope">age</param>
  </interceptor>
</interceptors>

The SessionFlowExecKeyInterceptor puts the flow execution key in the session rather than having it as a hidden field on the form that submitted back. The FlowScopeInterceptor takes a common seperated list of variables and binds them to flow scope. Before an action executes, this interceptor looks in flow scope and populates the corresponding properties on the webwork action. After the action has executed, the variables are retrieved from the action and the updated values are put back into flow scope.

Step 4 - Configure the FlowAction so Spring Webflows can be executed

<action name="FlowAction" class="com.googlecode.webworkwebflow.FlowAction">
  <interceptor-ref name="sessionFlowExecKey" />
  <interceptor-ref name="defaultStack" />
  <param name="flowId">rating-flow</param>
  <result name="ageEnter" type="redirect">
    AgeEnter.action
  </result>
  <result name="ageEnterJSP">/example/enterage.jsp</result>
  <result name="calcRate" type="redirect">
    CalcRate.action
  </result>
  <result name="finish">/example/finished.jsp</result>
</action>

For each view-state defined in the flow xml definition, there should be a corresponding result entry in the FlowAction definition. (Or a global result for the view state)

Step 5 - Access the flow

The flow can now be launched by accessing the FlowAction.